package com.transcargo.action;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.transcargo.errors.ErrorList;
import com.transcargo.data.Cache;
import com.transcargo.db.db;
import com.transcargo.db.dbException;
import com.transcargo.geo.GeoObjectNotFoundException;
import com.transcargo.users.Contact;
import com.transcargo.users.User;
import com.transcargo.users.UserNotFoundException;
import com.transcargo.util.Checker;
import com.transcargo.util.Normalizer;

public class PostCargoAction extends AuthAction {
	private String datetype = "";
	private String date_from = "";
	private String date_to = "";
	private String from = "";
	private String regFrom = "";
	private String to = "";
	private String regTo = "";
	private String owntransport = "";
	private String cargo_type = "";
	private String volume = "";
	private String weight = "";
	private String tir = "";
	private String adr = "";
	private String payment_type = "";
	private String bid = "";
	private String payment_curr = "";
	private String urgent = "";
	private String urgent_time = "";
	private String passing = "";
	private String comments = "";
	private String contact = "";
	private String loading="";
	private String cargo = "";
	private String customs = "";
	private String cars = "";
	private String combined = "";
	private String times = "";
	private int cid_from = 0;
	private int rid_from = 0;
	private int ctid_from = 0;
	private int cid_to = 0;
	private int rid_to = 0;
	private int ctid_to = 0;
	
	private void servletGetValues(HttpServletRequest request) throws ServletParametersException {
		datetype = request.getParameter("datetype");
		date_from = request.getParameter("date_from");
		date_to = request.getParameter("date_to");
		from = request.getParameter("from");
		regFrom = request.getParameter("regfrom");
		to = request.getParameter("to");
		regTo = request.getParameter("regto");
		owntransport = request.getParameter("owntransport");
		cargo_type = request.getParameter("cargo_type");
		volume = request.getParameter("volume");
		weight = request.getParameter("weight");
		tir = request.getParameter("tir");
		adr = request.getParameter("adr");
		payment_type = request.getParameter("payment_type");
		bid = request.getParameter("bid");
		payment_curr = request.getParameter("payment_curr");
		urgent = request.getParameter("urgent");
		urgent_time = request.getParameter("urgenttime");
		passing = request.getParameter("passing");
		comments = request.getParameter("comments");
		contact = request.getParameter("contact");
		cargo = request.getParameter("cargo");
		customs = request.getParameter("customs");
		cars = request.getParameter("cars");
		combined = request.getParameter("combined");
		times = request.getParameter("times");
		
		if (from == null) from="";
		if (regFrom == null) regFrom="";
		if (to == null) to="";
		if (regTo == null) regTo="";
		if (to == null) to="";
		if (owntransport == null) owntransport="";
		if (tir == null) tir="";
		if (bid == null) bid="";
		if (volume == null) volume="";
		if (weight == null) weight="";
		if (urgent == null) urgent="";
		if (passing == null) passing="";
		if (comments == null) comments="";
		if (cargo == null) cargo="";
		if (customs == null) customs="";
		if (cars == null) cars="1";
		if (combined == null) combined="";
		if (times == null) times="5";
        if (!urgent.equals("on") || urgent_time == null || urgent_time.length() == 0) urgent_time="0:00";
		
        Iterator<String> it = Cache.getTransportLoadings().keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            String b = request.getParameter("load" + key);
            if (b != null && b.equals("on")) loading = loading.concat(loading.length() > 0 ? "," + key : key);
        }
        StringTokenizer tok1 = new StringTokenizer(regFrom,"-");
        StringTokenizer tok2 = new StringTokenizer(regTo,"-");
        try {
	        switch (tok1.countTokens()) {
	        	case 3:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		rid_from = Integer.parseInt(tok1.nextToken());
	        		ctid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        	case 2:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		rid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        	case 1:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        }
	        switch (tok2.countTokens()) {
	        	case 3:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		rid_to = Integer.parseInt(tok2.nextToken());
	        		ctid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        	case 2:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		rid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        	case 1:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        }
        } catch (NumberFormatException e) {
        	System.out.println("WARNING!! Invalid number in regions: " + e.getMessage());
        }
    }
    private void servletValidateValues() throws ServletValidationException, ServletActionException {
    	User user = null;
		try {
			user = new User(User_Id, dbase);
		}  catch (UserNotFoundException e) {
			System.out.println("User Not Found exception: " + e.getMessage());
			throw new ServletActionException();
		} catch (GeoObjectNotFoundException e) {
			System.out.println("Geo Object not found: " + e.getMessage());
			throw new ServletActionException();
		}
    	if (contact != null && contact.length() > 0) {
    		int contact_id = Integer.parseInt(contact);
    		if (contact_id > 0) {
    			Contact c = user.getContact(contact_id);
    			if (c == null) {
    				throw new ServletValidationException("Invalid contact value");
    			}
    		}
    	}
        try {
	        if (weight.length() > 0) {
	        	weight = weight.replace(",", ".");
	        	if (Float.parseFloat(weight) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
        }
        try {
	        if (times.length() > 0) {
	        	Integer.parseInt(times);
	        }
        
        } catch (NumberFormatException e) {
        	times = "1";
        }
        try {
	        if (cars.length() > 0) {
	        	Integer.parseInt(cars);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARSNUMBER);
        }
        try {
	        if (volume.length() > 0) {
	        	volume = volume.replace(",", ".");
	        	if (Integer.parseInt(volume) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
        }
        try {
	        if (bid.length() > 0) {
	        	bid = bid.replace(",", ".");
	        	if (Float.parseFloat(bid) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
        }
        if (cargo.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CARGONAME_MISSING);
        if (cargo.length() >255) throw new ServletValidationException(ErrorList.ERROR_STR_CARGONAME_TOO_LONG);
        if (cargo_type.length() == 0 || Integer.parseInt(cargo_type) == 0 || Integer.parseInt(cargo_type) > 255) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARGO);
        if (loading.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_LOADING_MISSING);
        if (volume.length() == 0 || Integer.parseInt(volume) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CVOLUME_MISSING);
        if (weight.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_WEIGHT_MISSING);
        if (Integer.parseInt(volume) > 200) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
        if (Integer.parseInt(weight) > 200) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
        if (cars.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CARSNUMBER_MISSING);
        if (Integer.parseInt(cars) == 0 || Integer.parseInt(cars) > 100) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARSNUMBER);
        if (adr.length() > 0 && (Integer.parseInt(adr) == 0 || Integer.parseInt(adr) > 9)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_ADR);
        if (date_from == null || date_from.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_MISSING);
        if (date_to == null || date_to.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_MISSING);
        if (!Checker.CheckDate(date_from)) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_INVALID);
        if (!Checker.CheckDate(date_to)) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_INVALID);
        if (from.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CITYFROM_MISSING);
        if (cid_from == 0) throw new ServletValidationException(ErrorList.ERROR_STR_COUNTRYFROM_MISSING);
        if (from.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_CITYFROM_TOO_LONG);
        if (to.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_CITYTO_TOO_LONG);
        if (to.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CITYTO_MISSING);
        if (cid_to == 0) throw new ServletValidationException(ErrorList.ERROR_STR_COUNTRYTO_MISSING);
        if (bid.length() > 12) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
        if (Integer.parseInt(payment_type) > 255) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_PAYMENTTYPE);
        if (!payment_curr.equals("-") && (Integer.parseInt(payment_curr) == 0 || Integer.parseInt(payment_curr) > 255)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_PAYMENTCURRENCY);
        if (urgent.equals("on") && !Checker.CheckTime(urgent_time)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_URGENTTIME);
        if (comments.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_COMMENTS_TOO_LONG);
        if (urgent.equals("on") && datetype.equals("off")) throw new ServletValidationException(ErrorList.ERROR_STR_URGENT_PERMANENT);
        if ((Integer.parseInt(times) == 0 || Integer.parseInt(times) > 7) && datetype.equals("off")) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_TIMES);
    }
    private void servletExecuteAction() throws ServletActionException {
    	try {
	        db.PreStatement pre = dbase.CreateStatement("INSERT INTO posted_cargo (user_id, " +
	        		"date_load, " +
	        		"date_unload, " +
	        		"country_id_from, " +
	        		"region_id_from, " +
	        		"city_id_from, " +
	        		"city_value_from, " +
	        		"country_id_to, " +
	        		"region_id_to, " +
	        		"city_id_to, " +
	        		"city_value_to, " +
	        		"cargo, " +
	        		"cars, " +
	        		"type, " +
	        		"loading, " +
	        		"tir, " +
	        		"adr, " +
	        		"weight, " +
	        		"volume, " +
	        		"payment_bid, " +
	        		"payment_type, " +
	        		"payment_currency, " +
	        		"urgent, " +
	        		"urgent_time, " +
	        		"combined, " +
	        		"passing, " +
	        		"customs, " +
	        		"comments, " +
	        		"permanent, " + 
	        		"times) " +
	        		"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
	        pre.Insert((contact != null && contact.length() > 0)?(Integer.parseInt(contact) * 100000000 + User_Id):User_Id);
	        pre.Insert(Normalizer.NormalizeDate(date_from));
	        pre.Insert(Normalizer.NormalizeDate(date_to));
	        pre.Insert(cid_from);
	        pre.Insert(rid_from);
	        pre.Insert(ctid_from);
	        pre.Insert(from);
	        pre.Insert(cid_to);
	        pre.Insert(rid_to);
	        pre.Insert(ctid_to);
	        pre.Insert(to);
	        pre.Insert(cargo);
	        pre.Insert(cars);
	        pre.Insert(cargo_type);
	        pre.Insert(loading);
	        pre.Insert(tir.equals("on")?"1":"0");
	        pre.Insert(adr.length()>0?adr:"0");
	        pre.Insert(weight);
	        pre.Insert(volume);
	        pre.Insert(bid.length()>0?bid:"0");
	        pre.Insert(payment_type);
	        pre.Insert(payment_curr.equals("-")?"0":payment_curr);
	        pre.Insert(urgent.equals("on")?"1":"0");
	        pre.Insert(urgent_time);
	        pre.Insert(combined.equals("on")?"1":"0");
	        pre.Insert(passing.equals("on")?"1":"0");
	        pre.Insert(customs.equals("on")?"1":"0");
	        pre.Insert(comments);
	        pre.Insert(datetype.equals("off")?"1":"0");
	        pre.Insert(times);
	        dbase.executeUpdate(pre);
    	} catch (dbException e) {
			System.out.println("Db exception: " + e.getMessage());
			throw new ServletActionException();
		} catch (SQLException e) {
			System.out.println("SQL exception: " + e.getMessage());
			throw new ServletActionException();
		} 
    }
	        
    public void processAction(HttpServletRequest request, HttpServletResponse response) throws ServletException {
		try {
            servletGetValues(request);
            servletValidateValues();
            servletExecuteAction();
            sendRedirect(response, "posts.jsp?i=1");
	    } catch (ServletParametersException e) {
            if (e.getMessage() != null) {
                sendError(response, new Exception(e.getMessage()));
            } else {
                sendRedirect(response, "postcargo.jsp");
            }
        }  catch (ServletValidationException e) {
            sendError(response, new Exception(e.getMessage()));
        }  catch (ServletActionException e) {
            sendError(response, new Exception("" + ErrorList.ERROR_STR_GENERIC));
        }
    }
}
